package com.booway.threadtemp.factoryimpl;


import java.util.Iterator;
import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.LinkedBlockingQueue;

import com.booway.threadtemp.stock.DefaultStock;
import com.booway.threadtemp.util.ThreadTempUtil;

/**
 * 默认的原料工厂
 * @author cuibo
 *
 * @param <P>
 */
public abstract class AbstractDefaultStockFactory<S extends DefaultStock<S, P>, P> extends AbstractFactory<S, P>
{
    
    /** 由于存在前置被暂停的原料 */
    private Queue<S> waitingPreStocks = new LinkedBlockingQueue<S>();
    
    public AbstractDefaultStockFactory()
    {
        super();
    }
    
    public AbstractDefaultStockFactory(int maxSyncCount)
    {
        super(maxSyncCount);
    }

    /**
     * 获取等待前置任务的原料
     * @return
     */
    public Queue<S> getWaitingPreStocks()
    {
        return new LinkedList<S>(waitingPreStocks);
    }

    @Override
    protected void doStockCompleteHook(S s, P result, Throwable cause)
    {
		 if (s.getCallBack() != null)
		 {
            s.getCallBack().onComplete(result);
            if (cause == null)
                s.getCallBack().onSuccess(result);
            else
                s.getCallBack().onError(cause);
		 }
    }
    
    @Override
    protected S getNextStock() throws InterruptedException
    {
    	S result = null;
        out:
        while (true)
        {
            // 先检测等待队列
            if (!ThreadTempUtil.isEmpty(waitingPreStocks))
            {
            	Iterator<S> ite = waitingPreStocks.iterator();
            	
            	in:
            	while (ite.hasNext())
            	{
    				S stock = ite.next();
    				if (ThreadTempUtil.isEmpty(stock.getPreStocks()))
                    {
    				    // 移除
                        ite.remove();
                        return stock;
                    }
                    for (S pre : stock.getPreStocks())
                    {
                        if (!checkStockHasDown(pre))
                        {
                            continue in;
                        }
                    }
                    // 移除
                	ite.remove();
                    return stock;
    			}
            	// 如果此时原料区域是空的，则继续轮循
            	if (ThreadTempUtil.isEmpty(stockQueue)) 
            	{
					continue out;
				}
            }
			result = getNextStockImpl();
            if (!ThreadTempUtil.isEmpty(result.getPreStocks()))
            {
        		// 检测前置是否完成
                for (S pre : result.getPreStocks())
                {
                    if (!checkStockHasDown(pre))
                    {
                        // 添加到等待队列中
                        waitingPreStocks.add(result);
                        // 继续拿下一个
                        continue out;
                    }
                }
                // 跳出返回result
                break;
            } else
            {
            	return result;
            }
        }
        return result;
    }
    
    @Override
    public void clearFactory()
    {
        super.clearFactory();
        waitingPreStocks.clear();
    }

    @Override
    public void shutDown()
    {
        super.shutDown();
        waitingPreStocks = null;
    }

    protected abstract S getNextStockImpl() throws InterruptedException;
    
    
}
